#include <ros/ros.h>
#include <opencv2/opencv.hpp>
#include <zbar.h> // zbar库 sudo apt-get install libzbar0 libzbar-dev
#include <iostream>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/Image.h>

// 全局扫描器
zbar::ImageScanner scanner;

// 全局网格参数
int grid_rows = 1;
int grid_cols = 3;

// 可调节网格的二维码检测函数
void detectQRCodeInGrid(cv::Mat& frame, int rows = 3, int cols = 3) {
    // 获取图像尺寸
    int img_height = frame.rows;
    int img_width = frame.cols;
    
    // 计算每个网格的尺寸
    int grid_height = img_height / rows;
    int grid_width = img_width / cols;

    // 网格检测
    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < cols; col++) {
            // 计算当前网格的ROI区域
            int start_y = row * grid_height;
            int start_x = col * grid_width;
            
            // 处理边界情况，确保最后一行/列包含剩余像素
            int end_y = (row == rows - 1) ? img_height : (row + 1) * grid_height;
            int end_x = (col == cols - 1) ? img_width : (col + 1) * grid_width;
            
            cv::Rect roi(start_x, start_y, end_x - start_x, end_y - start_y);
            cv::Mat grid_frame = frame(roi);
            
            // 转换为灰度图
            cv::Mat gray;
            cv::cvtColor(grid_frame, gray, cv::COLOR_BGR2GRAY);
            cv::Sobel(gray, gray, CV_8U, 1, 0, 1); // dx=1, dy=0表示x方向，核大小为1

            cv::Mat binary;
            cv::threshold(gray, binary, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);

            cv::imshow("sobel", gray);
            cv::imshow("binary", binary);

            // 将OpenCV图像转换为ZBar图像
            zbar::Image image(grid_frame.cols, grid_frame.rows, "Y800", binary.data, grid_frame.cols * grid_frame.rows);

            

            // 扫描当前网格
            int n = scanner.scan(image);

            // 如果检测到符号，输出信息并绘制
            if (n > 0) {
                std::cout << "网格 [" << row << "," << col << "] 检测到 " << n << " 个符号:" << std::endl;
                
                for (auto symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol) {
                    std::cout << "  解码类型: " << symbol->get_type_name() << std::endl;
                    std::cout << "  解码数据: " << symbol->get_data() << std::endl;

                    // 在原图像上绘制矩形框（需要调整坐标到原图坐标系）
                    std::vector<cv::Point> points;
                    for (int i = 0; i < symbol->get_location_size(); i++) {
                        int x = symbol->get_location_x(i) + start_x;
                        int y = symbol->get_location_y(i) + start_y;
                        points.push_back(cv::Point(x, y));
                    }
                    cv::polylines(frame, points, true, cv::Scalar(0, 255, 0), 2);
                    
                    // 在网格上添加标识
                    cv::putText(frame, "Grid[" + std::to_string(row) + "," + std::to_string(col) + "]", 
                               cv::Point(start_x + 10, start_y + 30), 
                               cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 0, 0), 1);
                }
            }
            
            // 绘制网格分割线（可选，用于可视化）
            if (col < cols - 1) {
                cv::line(frame, cv::Point(end_x, 0), cv::Point(end_x, img_height), cv::Scalar(255, 255, 255), 1);
            }
            if (row < rows - 1) {
                cv::line(frame, cv::Point(0, end_y), cv::Point(img_width, end_y), cv::Scalar(255, 255, 255), 1);
            }
        }
    }
}

// 图像回调函数
void imageCallback(const sensor_msgs::ImageConstPtr& msg) {
    try {
        // 将ROS图像消息转换为OpenCV图像
        cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
        cv::Mat frame = cv_ptr->image.clone();
        
        // 调用可调节网格的二维码检测函数
        detectQRCodeInGrid(frame, grid_rows, grid_cols);
        cv::putText(frame, "Grid: " + std::to_string(grid_rows) + "x" + std::to_string(grid_cols), 
                   cv::Point(10, 30), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(255, 255, 0), 2);
        cv::putText(frame, "Q/A:rows W/S:cols R:reset", 
                   cv::Point(10, 60), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 0), 1);
        cv::imshow("QRCode Scanner - Grid Detection", frame);
        int key = cv::waitKey(1);
        
    } catch (cv_bridge::Exception& e) {
        ROS_ERROR("cv_bridge exception: %s", e.what());
    }
}

int main(int argc, char** argv) {
    // 初始化ROS节点
    ros::init(argc, argv, "qrcode_detector");
    ros::NodeHandle nh;
    
    // 限制范围
    grid_rows = std::max(1, std::min(10, grid_rows));
    grid_cols = std::max(1, std::min(10, grid_cols));
    
    // 初始化ZBar扫描器
    scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
    
    // 订阅图像话题
    ros::Subscriber image_sub = nh.subscribe("/usb_cam_4060h/image_raw", 1, imageCallback);
    
    ROS_INFO("QRCode detector started, 网格设置: %d行 x %d列", grid_rows, grid_cols);
    ROS_INFO("键盘控制:");
    ROS_INFO("  Q/A: 增加/减少行数");
    ROS_INFO("  W/S: 增加/减少列数");
    ROS_INFO("  R: 重置为3x3");
    
    // 进入ROS消息循环
    ros::spin();
    
    return 0;
}